package com.allwees.core.common.util;

import org.apache.commons.lang3.ArrayUtils;

import java.math.BigDecimal;

/**
 * 金额精确计算
 *
 * @author yangylsky
 * @since 2019-10-17
 */
public class MoneyUtil {
    public static boolean isValidPrice(BigDecimal money) {
        return money != null && BigDecimal.ZERO.compareTo(money) < 0;
    }

    public static boolean isLtEqZero(BigDecimal money) {
        return money == null || money.compareTo(BigDecimal.ZERO) <= 0;
    }

    /**
     * 是否null 或者 0
     *
     * @return
     */
    public static boolean isNullOrZero(BigDecimal money) {
        return money == null || money.compareTo(BigDecimal.ZERO) == 0;
    }

    /**
     * 是否null 或者 0
     *
     * @return
     */
    public static boolean isNullOrLtEqZero(BigDecimal money) {
        return money == null || money.compareTo(BigDecimal.ZERO) <= 0;
    }

    /**
     * 精确加法
     *
     * @param source
     * @param targets
     * @return
     */
    public static BigDecimal add(BigDecimal source, BigDecimal... targets) {
        if (source == null) {
            return source;
        }
        if (ArrayUtils.isEmpty(targets)) {
            return source;
        }
        for (BigDecimal target : targets) {
            if (target != null) {
                source = source.add(target);
            }
        }
        return source.setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 精确减法
     *
     * @param source
     * @param targets
     * @return
     */
    public static BigDecimal sub(BigDecimal source, BigDecimal... targets) {
        return sub(source, 2, targets);
    }

    /**
     * 精确减法
     *
     * @param source
     * @param targets
     * @return
     */
    public static BigDecimal sub(BigDecimal source, int scale, BigDecimal... targets) {
        if (source == null) {
            return source;
        }
        if (ArrayUtils.isEmpty(targets)) {
            return source;
        }
        for (BigDecimal target : targets) {
            if (target != null) {
                source = source.subtract(target);
            }
        }
        return source.setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 精确乘法
     *
     * @param source
     * @param targets
     * @return
     */
    public static BigDecimal mul(BigDecimal source, BigDecimal... targets) {
        return mul(source, 2, targets);
    }

    /**
     * 精确乘法
     *
     * @param source
     * @param targets
     * @return
     */
    public static BigDecimal mul(BigDecimal source, int scale, BigDecimal... targets) {
        if (source == null) {
            return source;
        }
        if (ArrayUtils.isEmpty(targets)) {
            return source;
        }
        for (BigDecimal target : targets) {
            if (target != null) {
                source = source.multiply(target);
            }
        }
        return source.setScale(scale, BigDecimal.ROUND_HALF_UP);
    }


    /**
     * 精确除法（2位小数）
     *
     * @param source
     * @param target
     * @return
     */
    public static BigDecimal div(BigDecimal source, BigDecimal target) {
        return div(source, target, 2);
    }

    /**
     * 精确除法
     *
     * @param source
     * @param target
     * @param scale
     * @return
     */
    public static BigDecimal div(BigDecimal source, BigDecimal target, int scale) {
        return source.divide(target, scale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal setScale(BigDecimal source, int scale) {
        return source.setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal setScale(BigDecimal source) {
        return setScale(source, 2);
    }

    /**
     * 判断2个金额是否相等
     *
     * @param money1
     * @param money2
     * @return
     */
    public static boolean equals(BigDecimal money1, BigDecimal money2) {
        return (money1 == null && money2 == null) || (money1 != null && money2 != null && money1.compareTo(money2) == 0);
    }

    /**
     * 判断money1是否大于money2
     *
     * @param money1
     * @param money2
     * @return
     */
    public static boolean biggerThan(BigDecimal money1, BigDecimal money2) {
        if (money1 != null) {
            return money2 == null || money1.compareTo(money2) > 0;
        } else {
            return false;
        }
    }

    /**
     * 不同币种兑换
     *
     * @param amount
     * @param fromCurrency
     * @param toCurrency
     * @return
     */
    public static BigDecimal exchange(BigDecimal amount, String fromCurrency, String toCurrency) {
        if (fromCurrency.equals(toCurrency)) {
            return amount;
        }
        throw new UnsupportedOperationException("还未实现币种兑换");
    }

    /**
     * @param amt1
     * @param amt2
     * @return
     */
    public static BigDecimal max(BigDecimal amt1, BigDecimal amt2) {
        if (amt1 == null) {
            return amt2;
        }
        if (amt2 == null) {
            return BigDecimal.ZERO;
        }
		return amt1.compareTo(amt2) > 0 ? amt1 : amt2;
    }

	/**
	 * @param amt1
	 * @param amt2
	 * @return
	 */
	public static BigDecimal min(BigDecimal amt1, BigDecimal amt2) {
		if (amt1 == null) {
			return amt2;
		}
		if (amt2 == null) {
			return BigDecimal.ZERO;
		}
		return amt1.compareTo(amt2) > 0 ? amt2 : amt1;
	}
}
